home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / doc.lha / doc.doc / puma.doc < prev    next >
Text File  |  1992-09-25  |  74KB  |  2,592 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11. ___________________________________________________________________
  12.  
  13.                                    Puma - A Generator
  14.                                    for the Transformation
  15.                                    of Attributed Trees
  16.  
  17.                                    J. Grosch
  18.  
  19.  
  20. ___________________________________________________________________
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50. ___________________________________________________________________
  51.                                    GESELLSCHAFT FUeR MATHEMATIK
  52.                                    UND DATENVERARBEITUNG MBH
  53.  
  54.                                    FORSCHUNGSSTELLE FUeR
  55.                                    PROGRAMMSTRUKTUREN
  56.                                    AN DER UNIVERSITAeT KARLSRUHE
  57. ___________________________________________________________________
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.                                    Project
  76.  
  77.                              Compiler Generation
  78.  
  79.          ___________________________________________________________
  80.  
  81.         Puma - A Generator for the Transformation of Attributed Trees
  82.  
  83.  
  84.                                  Josef Grosch
  85.  
  86.  
  87.                                 Nov. 22, 1991
  88.  
  89.          ___________________________________________________________
  90.  
  91.  
  92.                                 Report No. 26
  93.  
  94.  
  95.                              Copyright c 1991 GMD
  96.  
  97.  
  98.             Gesellschaft fuer Mathematik und Datenverarbeitung mbH
  99.                 Forschungsstelle an der Universitaet Karlsruhe
  100.                           Vincenz-Priesznitz-Str. 1
  101.                                D-7500 Karlsruhe
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.                                      Puma                                    1
  135.  
  136.  
  137.         Puma - A Generator for the Transformation of Attributed Trees
  138.  
  139. 1.  Introduction
  140.  
  141. Puma is a tool supporting the transformation and  manipulation  of  attributed
  142. trees.  It  is  based  on  pattern-matching, unification, and recursion.  Puma
  143. cooperates with the generator for abstract syntax  trees  ast  [Gro91],  which
  144. already  supports  the  definition, creation, and storage of attributed trees.
  145. Puma adds a concise notation for the analysis  and  synthesis  of  trees.  The
  146. pattern-matching  capability facilitates the specification of decision tables.
  147. Puma provides the implicit declaration of variables, strong type checking with
  148. respect  to trees, and checks the single assignment restriction for variables.
  149. The output is the source code of a program module written in one of the target
  150. languages  C  or Modula-2. This module implements the specified transformation
  151. routines. It can be integrated easily with arbitrary program  code.  The  gen-
  152. erated routines are optimized with respect to common subexpression elimination
  153. and tail recursion.
  154.  
  155.      The intended use of this tool proceeds in three steps: First, a  tree  is
  156. constructed  either  by a parser, a previous transformation phase, or whatever
  157. is appropriate.  Second, the attributes in the tree are evaluated either using
  158. an attribute grammar based tool, by a puma specified tree traversal and attri-
  159. bute computations, or by hand-written code.  Third,  the  attributed  tree  is
  160. transformed  or mapped to another data structure by a puma generated transfor-
  161. mation module.  These steps can be executed one after the  other  or  more  or
  162. less  simultaneously.   Besides  trees,  puma  can handle attributed graphs as
  163. well, even cyclic ones. Of course the cycles have to be detected in  order  to
  164. avoid  infinite  loops. A possible solution uses attributes as marks for nodes
  165. already visited.
  166.  
  167.      A transformer module can make use of attributes in the following ways: If
  168. attribute values have been computed by a preceding attribute evaluator and are
  169. accessed in read only mode then this  corresponds  to  the  three  step  model
  170. explained  above.  A puma generated module can also evaluate attributes on its
  171. own. A further possibility is that an attribute evaluator can call  puma  sub-
  172. routines  in  order to compute attributes. This is especially of interest when
  173. attributes depend on tree-valued arguments.
  174.  
  175.      The tool supports two  classes  of  tree  transformations:  mappings  and
  176. modifications.  Tree mappings map an input tree to arbitrary output data.  The
  177. input tree is accessed in read only mode and left  unchanged.  Tree  modifica-
  178. tions change a tree by e. g. computing and storing attributes at tree nodes or
  179. by changing the tree structure. In this case the tree data structure serves as
  180. input as well as output and it is accessed in read and write mode.
  181.  
  182.      The first class covers applications like the generation  of  intermediate
  183. languages  or  machine  code. Trees are mapped to arbitrary output like source
  184. code, assembly code, binary machine code,  linearized  intermediate  languages
  185. like  P-Code,  or  another  tree structure. A further variant of mapping is to
  186. emit a sequence of procedure calls which are handled by an abstract data type.
  187.  
  188.      The second class covers applications like semantic analysis or  optimiza-
  189. tion.  Trees  are  decorated  with  attribute  values, properties of the trees
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.                                      Puma                                    2
  201.  
  202.  
  203. corresponding to context conditions are checked, or trees are changed in order
  204. to reflect optimizing transformations.
  205.  
  206.      The contents of this manual is organized as follows: Section 2  gives  an
  207. overview  and  describes the cooperation of puma and ast.  Section 3 describes
  208. the specification language of puma.  Section 4 describes the output  of  puma.
  209. Section  5 contains the UNIX manual page.  Appendix 1 contains the syntax sum-
  210. mary.  Appendix 2 presents an example from a compiler for MiniLAX.  Appendix 3
  211. lists  the  type  specific  equality operations for the target languages C and
  212. Modula-2.
  213.  
  214. 2.  Overview
  215.  
  216. The input of a transformer is a tree which might be decorated with attributes.
  217. The  structure  of  the  legal  input trees and the desired transformation are
  218. described in two separate documents.  Both  documents  are  processed  by  the
  219. separate  tools ast and puma.  The cooperation between those tools is depicted
  220. in Figure 1.  The  structure  of  the  trees  including  their  attributes  is
  221. described by a tree grammar and is fed into ast.  Ast produces the source code
  222. of a module that defines, stores, and manipulates the specified  tree  and  an
  223. internal  description  of  the  tree  in  the file Tree.TS.  This file and the
  224. description of the intended transformation are the input of puma.   Puma  gen-
  225. erates  a module that implements the specified transformation by a set of sub-
  226. programs which use the  tree  module  produced  by  ast.   The  two  generated
  227. modules,  which are named Tree and Trafo by default, consist of two files: The
  228. header, interface, or  definition  part  and  the  implementation  part.  Both
  229. modules  must  be compiled and linked, eventually with other modules, to yield
  230. an executable program.
  231.  
  232.      For the following we assume the reader to be familiar with the tool  ast.
  233. Ast's  input  language  is used to define the node types, the subtype relation
  234. between the node types, and the children and  attributes  of  the  node  types
  235. including  their  data types. This input language is described in the ast user
  236. manual [Gro91].
  237.  
  238. 3.  Input Language
  239.  
  240. The following sections define the syntax and the semantics of a puma  specifi-
  241. cation.  Appendix  1  contains  a  summary  of the precise syntax of the input
  242. language in BNF notation.
  243.  
  244. 3.1.  Notation
  245.  
  246. An EBNF notation is used in the following to describe the  syntax  of  a  puma
  247. specification. The meaning of the meta symbols is as follows:
  248.  
  249.  
  250.  
  251.  
  252.  
  253.                      Fig. 1: Cooperation of puma and ast
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.                                      Puma                                    3
  267.  
  268.  
  269.     =               introduces the right-hand side of a grammar rule
  270.     |               introduces alternatives (usually used to separate alternatives)
  271.     [ ]             square brackets enclose optional parts
  272.     { }             curly brackets denote repetition zero, one, or more times
  273.     non alpha-numeric characters
  274.                     terminal symbol
  275.     ' character '   terminal symbol
  276.     all upper-case wordterminal symbol
  277.     other word      nonterminal symbol
  278.  
  279.  
  280. 3.2.  Lexical Conventions
  281.  
  282. The input of puma consists of identifiers, numbers, keywords, operators,  del-
  283. imiters, comments, white space, and so called target code.
  284.  
  285.      Identifiers are sequences of letters, digits, and underscore characters _
  286. that  start  with  a  letter  or  an  underscore character _.  The case of the
  287. letters is significant:
  288.  
  289.     x   NoName   k2   mouse_button
  290.  
  291.  
  292. Numbers comprise integers and reals in decimal notation.  They are written  as
  293. in the target language:
  294.  
  295.     0   007   1991   31.4E-1
  296.  
  297.  
  298. The following words are reserved as keywords and may not be used  as  identif-
  299. iers:
  300.  
  301.     AND           BEGIN         CLOSE         DIV           EXPORT
  302.     EXTERN        FAIL          FUNCTION      GLOBAL        IMPORT
  303.     IN            LOCAL         MOD           NIL           NL
  304.     NOT           OR            PREDICATE     PROCEDURE     PUBLIC
  305.     REF           REJECT        RETURN        TRAFO         TREE
  306.  
  307.  
  308. Operators are either symbols from the following list or sequences  of  charac-
  309. ters  introduced  by  a  backslash  \  and terminated by white space.  Escaped
  310. operators are used for operators not known to puma.  They are written  to  the
  311. output with the backslash \ removed.
  312.  
  313.     !      !=     #      %      &      &&     *      +      ++     -      --
  314.     ->     .      /      <      <<     <=     <>     =      ==     >      >=
  315.     >>     ^      |      ||     AND    DIV    IN     MOD    NOT    OR
  316.  
  317.  
  318.     Examples of escaped operators:
  319.     \,    \?    \:    \(void)    \(int*)    \(struct \node)
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.                                      Puma                                    4
  332.  
  333.  
  334. The following characters are delimiters:
  335.  
  336.     (   )   ,   .   ..   ...   :   :=   :-   ;   =>   ?   [   ]   _   {   }
  337.  
  338.  
  339. The delimiters .. and ... can be used alternatively, as can be ? and :-.  Com-
  340. ments are characters enclosed in /* and */ as in C. They may not be nested:
  341.  
  342.     /* comment */
  343.  
  344.  
  345. Target code are declarations, statements, or expressions written in the target
  346. language  and  enclosed  in curly brackets { }.  Target code may contain curly
  347. brackets { } as long as these are  either  properly  nested  or  contained  in
  348. strings or in character constants.  Unnested curly brackets outside of strings
  349. or character constants have to be escaped by a backslash character \. In  gen-
  350. eral  all  characters outside of strings or character constants may be escaped
  351. by a backslash character \.  This escape mechanism is not necessary in strings
  352. and  character  constants.   Target  code  is  usually  copied  unchecked  and
  353. unchanged to the output.
  354.  
  355.     { x = 1; }
  356.     { { char c = '}'; } }
  357.     { printf ("}\n"); }
  358.  
  359.  
  360. White space characters like blanks, tab characters,  form  feeds,  and  return
  361. characters are ignored.
  362.  
  363. 3.3.  Structure
  364.  
  365. The input of puma consists of a header, target code sections, and  a  list  of
  366. subroutines.
  367.  
  368.     Syntax:
  369.     Input  = [ TRAFO Ident ] [ TREE Idents ] [ PUBLIC Idents ] [ EXTERN Idents ]
  370.              { TargetCodes } { Subroutine }
  371.     Idents = Ident { , Ident }
  372.  
  373.  
  374.      The identifier behind the keyword TRAFO determines the name of  the  gen-
  375. erated module. The default name is Trafo.
  376.  
  377.      The identifiers behind the keyword TREE refer to the tree modules  to  be
  378. manipulated.  A  puma  module  can  not only handle one tree definition but an
  379. arbitrary number.  There must be a tree grammar for every tree  and  they  all
  380. must  have  been converted to their internal format with ast.  More precisely,
  381. those names refer to so-called views of a tree definition. Roughly speaking, a
  382. view selects a subset of a tree definition.  See the documentaion of ast for a
  383. description of this concept.  If the keyword TREE is missing then the  follow-
  384. ing serves as default:
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.                                      Puma                                    5
  396.  
  397.  
  398.     TREE Tree
  399.  
  400. Therefore an empty list of tree definitions has to be given as:
  401.  
  402.     TREE
  403.  
  404.  
  405.      The identifiers behind the keyword PUBLIC specify those subroutines  that
  406. should become visible from outside the module. External declarations for these
  407. subroutines are inserted automatically in the interface part of the  generated
  408. module.
  409.  
  410.      The identifiers behind the keyword EXTERN specify  those  identifiers  of
  411. global,  local,  or  external  variables and subroutines that are used in some
  412. subroutines but that are not declared from the point of view  of  puma.   They
  413. may be used in expressions and statements that are checked by the tool without
  414. causing a message.
  415.  
  416.     Example:
  417.     TRAFO ICode TREE Tree Definitions PUBLIC Code
  418.     EXTERN ADD CHK ENT Emit
  419.  
  420.  
  421. 3.4.  Target Code
  422.  
  423. A puma specification may contain  several  sections  containing  target  code.
  424. Target code is code written in the target language. It is copied unchecked and
  425. unchanged to certain places in the generated module.
  426.  
  427.     Syntax:
  428.     TargetCodes =
  429.     | EXPORT TargetCode
  430.     | GLOBAL TargetCode
  431.     | BEGIN  TargetCode
  432.     | CLOSE  TargetCode
  433.  
  434.  
  435. The meaning of the different sections is as follows:
  436.  
  437. EXPORT:     declarations to be included in the interface part.
  438.  
  439. GLOBAL:     declarations to be included in the implementation part  at  global
  440.             level.
  441.  
  442. BEGIN:      statements to initialize the declared data structures.
  443.  
  444. CLOSE:      statements to finalize the declared data structures.
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.                                      Puma                                    6
  460.  
  461.  
  462.     Example in C:
  463.     EXPORT { typedef int MyType; extern MyType Sum; }
  464.     GLOBAL {# include "Idents.h"
  465.              MyType Sum; }
  466.     BEGIN  { Sum = 0; }
  467.     CLOSE  { printf ("%d", Sum); }
  468.  
  469.  
  470.     Example in Modula-2:
  471.     EXPORT { TYPE MyType = INTEGER; VAR Sum: MyType; }
  472.     GLOBAL { FROM Idents IMPORT tIdent; }
  473.     BEGIN  { Sum := 0; }
  474.     CLOSE  { WriteI (Sum, 0); }
  475.  
  476.  
  477. 3.5.  Subroutines
  478.  
  479. A set of subroutines constitutes the main building blocks of a transformation.
  480. Like  in  programming languages, subroutines are parameterized abstractions of
  481. statements or expressions.  There are three kinds of subroutines:
  482.  
  483.     procedure: a subroutine acting as a statement
  484.     function: a subroutine acting as an expression and returning a value
  485.     predicate: a boolean function
  486.  
  487.  
  488.     Syntax:
  489.     Subroutine = Header [ EXTERN Idents ; ] [ LOCAL TargetCode ] { Rule }
  490.     Header     =
  491.     | PROCEDURE Ident ( [ Parameters ] [ => Parameters ] )
  492.     | FUNCTION  Ident ( [ Parameters ] [ => Parameters ] ) Type
  493.     | PREDICATE Ident ( [ Parameters ] [ => Parameters ] )
  494.     Parameters = [ REF ] [ Ident : ] Type { , [ REF ] [ Ident : ] Type }
  495.  
  496.  
  497. A subroutine consists of a header, an optional  target  code  section,  and  a
  498. sequence of rules.  The header specifies the kind of the subroutine, its name,
  499. and its parameters.  In case of a function, the type of the  result  value  is
  500. added.   This  type  is  restricted to types legal for function results in the
  501. target language (usually simple types and pointers).  Input and output parame-
  502. ters are separated by the symbol =>.  It suffices to give the type of a param-
  503. eter. A name for the formal parameter is optional.  Usually  input  parameters
  504. are passed by value and output parameters are passed by reference. The keyword
  505. REF can be used to pass input parameters by  reference,  too.  This  might  be
  506. necessary  in  case  of tree modifications when an input tree is replaced by a
  507. newly created one.  The identifiers behind the keyword  EXTERN  specify  those
  508. identifiers  of  global, local, or external variables and subroutines that are
  509. used within the subroutine but that are not declared from the point of view of
  510. puma.   They may be used in expressions and statements that are checked by the
  511. tool without causing a message.  The target code section is copied in front of
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.                                      Puma                                    7
  523.  
  524.  
  525. the body of the generated subprogram and may e. g. contain local declarations.
  526.  
  527.     Examples:
  528.     PROCEDURE Code (t: Tree) LOCAL { tObjects object; } ...
  529.     PREDICATE IsCompatible (Type, Type) ...
  530.     FUNCTION  ResultType (Type, Type, int) Type ...
  531.     PROCEDURE ResultType (Type, Type, int => Type) ...
  532.  
  533.  
  534. 3.6.  Types
  535.  
  536. Types are either predefined in the target language like int  and  INTEGER,  or
  537. user-defined  like  MyType,  or they are tree types like Expr.  A tree type is
  538. described by the name of a tree definition, a single node type, or a  list  of
  539. node  types  enclosed  in  brackets [ ]. In case of ambiguities the latter two
  540. kinds may be qualified by preceding the name of the tree definition. In  every
  541. case a tree-type defines a set of legal node types. The name of a tree defini-
  542. tion refers to every node type that is  defined  there.  A  single  node  type
  543. yields  a  set  with just this one element and a list of node types yields the
  544. union of all list elements.
  545.  
  546.     Syntax:
  547.     Type     =
  548.     | TreeType
  549.     | UserType
  550.     TreeType =
  551.     | Ident
  552.     | [ Ident . ] Ident
  553.     | [ Ident . ] '[' Idents ']'
  554.     UserType = Ident
  555.  
  556.  
  557.     Examples:
  558.     int                       /* predefined type             */
  559.     MyType                    /* user defined type           */
  560.     Tree                      /* tree type                   */
  561.     Expr                      /* node type                   */
  562.     Tree.Expr                 /* qualified node type         */
  563.     [Stats, Expr]             /* set of node types           */
  564.     Tree.[Stats, Expr]        /* qualified set of node types */
  565.  
  566.  
  567. 3.7.  Rules
  568.  
  569. A rule behaves like a branch in a case or switch statement. It consists  of  a
  570. list  of  patterns  (nonterminal  Patterns),  a  list of expressions, a return
  571. expression in case of a function, and a list of statements. Several neighbour-
  572. ing  rules  with  the same list of expressions, return expression, and list of
  573. statements may share those parts.  A list of a list of  patterns  (nonterminal
  574. PatternList)  is  equivalent  to  a  sequence  of rules having the sublists as
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.                                      Puma                                    8
  586.  
  587.  
  588. patterns and sharing the other parts.  Patterns and expressions may be  either
  589. positional  or  named.  The named entities have to follow the positional ones.
  590. For every position of a pattern or an expression at most  one  entity  may  be
  591. given.  The  named  elements are transformed into their positional form before
  592. type checking is performed. The parts of a rule may be  given  in  almost  any
  593. order as described by the exact syntax in Appendix 1.
  594.  
  595.      The number of patterns must agree with the number  of  input  parameters,
  596. and the types of the elements of those lists must be pairwise compatible.  The
  597. number of expressions must agree with the number of output parameters, and the
  598. types of the elements of those lists must be pairwise compatible.  The type of
  599. the expression after RETURN has to be compatible with the  result  type  of  a
  600. function.   The  type s of a pattern or an expression is said to be compatible
  601. to the type t of a formal parameter if s is a subtype of t (s  t).
  602.  
  603.     Syntax:
  604.     Rule        = [ PatternList ] [ => Exprs ] [ RETURN Expr ] ? { Statement ; } .
  605.     PatternList = Patterns { ; Patterns }
  606.     Patterns    =
  607.     | Pattern { , Pattern } { , Ident := Pattern }
  608.     | Ident := Pattern      { , Ident := Pattern }
  609.     Exprs       =
  610.     | Expr { , Expr } { , Ident := Expr }
  611.     | Ident := Expr   { , Ident := Expr }
  612.  
  613.  
  614.      The semantics of a rule is as follows: A rule may succeed  or  fail.   It
  615. succeeds  if all its patterns, statements, and expressions succeed - otherwise
  616. it fails. The patterns, statements, and expressions are checked for success in
  617. the  following  order:  First,  the patterns are checked from left to right. A
  618. pattern succeeds if it matches its corresponding input parameter as  described
  619. below.   Second,  the  statements  are  executed  in  sequence as long as they
  620. succeed.  The success of statements is defined below.  Third, the  expressions
  621. are  evaluated  from  left  to  right  and  their  results  are  passed to the
  622. corresponding output parameters.  In case  of  a  function,  additionally  the
  623. expression  after  RETURN  is evaluated and its result is returned as value of
  624. the function call.  The success of expressions is defined below, too.  If  all
  625. elements  of a rule succeed then the rule succeeds and the subroutine returns.
  626. If one element of a rule fails the process described above  stops  and  causes
  627. the  rule to fail. Then the next rule is tried.  This search process continues
  628. until either a successful rule is found or the end of the list is reached.  In
  629. the latter case the behaviour depends on the kind of the subroutine:
  630.  
  631.     A procedure signals a runtime error if option 'f' is set, otherwise it does nothing.
  632.     A predicate returns false.
  633.     A function signals a runtime error.
  634.  
  635. There is one exception to this definition of the semantics which is  explained
  636. later.   Note,  if  a predicate fails then the values of its output parameters
  637. are undefined.
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.                                      Puma                                    9
  649.  
  650.  
  651.     Examples:
  652.     PROCEDURE Code (t: Tree)
  653.        Plus  (Lop, Rop) ? Code (Lop); Code (Rop); Emit (ADD); .
  654.        Minus (Lop, Rop) ? Code (Lop); Code (Rop); Emit (SUB); .
  655.        ...
  656.  
  657.     PREDICATE IsCompatible (Type, Type)
  658.        Integer      , Integer       ?.
  659.        Real         , Real          ?.
  660.        Boolean      , Boolean       ?.
  661.        Array (t1, Lwb, Upb, _), Array (t2, Lwb, Upb, _) ? IsCompatible (t1, t2); .
  662.  
  663.     FUNCTION ResultType (Type, Type, int) Type
  664.        Integer      , Integer       , { Plus }      RETURN Integer  ?.
  665.        Real         , Real          , { Plus }      RETURN Real     ?.
  666.        Integer      , Integer       , { Times }     RETURN Integer  ?.
  667.        Real         , Real          , { Times }     RETURN Real     ?.
  668.        Integer      , Integer       , { Less }      RETURN Boolean  ?.
  669.        Real         , Real          , { Less }      RETURN Boolean  ?.
  670.  
  671.  
  672. 3.8.  Patterns
  673.  
  674. A pattern describes the shape at the top or root of a subtree.  A pattern  can
  675. be  a  decomposition of a tree, the keyword NIL, a label or a variable, one of
  676. the don't care symbols _ or .., or an expression. A decomposition  is  written
  677. as a node type followed by a list of patterns in parenthesis ( and ).  Option-
  678. ally, the node type may be qualified by a tree name and preceded by a label.
  679.  
  680.     Syntax:
  681.     Pattern =
  682.     | [ Label ] [ Ident . ] Ident [ ( [ Patterns ] ) ]
  683.     | [ Label ] NIL
  684.     | Ident
  685.     | _
  686.     | ..
  687.     | Expr
  688.     Label   =
  689.     | Ident :
  690.     | Ident :>
  691.  
  692.  
  693. The match between a pattern and a value is defined  recursively  depending  on
  694. the kind of the pattern:
  695.  
  696. -    A decomposition with a node type t matches a tree u with a root  node  of
  697.      type s if s is a subtype of t (s  t) and all subpatterns of t match their
  698.      corresponding subtrees or attributes of u.  If the node type is  preceded
  699.      by  a label l then a binding is established between l and u which defines
  700.      the label l to refer to the tree u.  If the label  l  is  followed  by  a
  701.      colon  :  then  l  has  the type of u.  If the label l is followed by the
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.                                      Puma                                   10
  713.  
  714.  
  715.      symbol :> then l has the type that is legal at  this  location.  This  is
  716.      either the type of a parameter or the type of a node type's child.
  717.  
  718. -    The pattern NIL matches the values NoTree or NIL.  If NIL is preceded  by
  719.      a  label  l  then a binding is established between l and the parameter or
  720.      child matching NIL.  l has the type that is legal at this location.  This
  721.      is either the type of a parameter or the type of a node type's child.
  722.  
  723. -    The first occurrence of a label l in a rule matches an arbitrary  subtree
  724.      or  attribute  value  u.   A binding is established between l and u which
  725.      defines the label l to refer to the value u.  The label can be used later
  726.      to  access  the associated value.  All further occurrences of the label l
  727.      within patterns of this rule match a subtree or an attribute value v only
  728.      if  u  is  equal to v.  The equality for trees is defined in the sense of
  729.      structural equivalence.  Two attributes are equal if they have  the  same
  730.      values.   This so-called non-linear pattern matching has to be enabled by
  731.      an option.  Without this option all further occurrences of a label l  are
  732.      treated as error.
  733.  
  734. -    The don't care symbol _ matches one arbitrary subtree or attribute value.
  735.  
  736. -    The don't care symbol .. matches any  number  of  arbitrary  subtrees  or
  737.      attribute values.
  738.  
  739. -    An expression matches a parameter or an attribute if both have  the  same
  740.      value.   The  equality  of values is defined as a type specific operation
  741.      (see section 3.11.).
  742.  
  743. The ambiguity between a node type without a list of  patterns  in  parentheses
  744. and  a  label is resolved in favor of the node type, by default. A node type t
  745. without a list of subpatterns is treated as t (..).  Puma has an  option  that
  746. disables  this  behaviour.  Then all node types require parentheses, otherwise
  747. they are considered as labels.
  748.  
  749.     Examples:
  750.     Binary                         /* a node type */
  751.     Tree.Binary
  752.     Binary (Lop, Rop, Operator)
  753.     a:Binary (_, b:>Binary (Lop, ..), Operator)
  754.                                    /* a, b, Lop, and Operator are labels */
  755.                                    /* a is of type Binary */
  756.                                    /* b is of type Expr   */
  757.     NIL
  758.     X                              /* a label */
  759.     k + 2
  760.     { Times }                      /* a named constant */
  761.  
  762.  
  763. 3.9.  Expressions
  764.  
  765. Expressions denote the computation of values or  the  construction  of  trees.
  766. Binary and unary operations as well as calls of external functions are written
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.                                      Puma                                   11
  778.  
  779.  
  780. as in the target language. Calls of puma functions and predicates  distinguish
  781. between input and output arguments.  Named arguments are not allowed in calls.
  782. The syntax for tree composition is similar to the syntax of patterns.   Again,
  783. the node type may be qualified by a tree name.
  784.  
  785.     Syntax:
  786.     Expr =
  787.     | [ Ident . ] Ident [ ( [ Exprs ] ) ]
  788.     | NIL
  789.     | Ident
  790.     | _
  791.     | ..
  792.     | Expr ( [ Exprs ] [ => Patterns ] )
  793.     | Expr Operator Expr
  794.     | Operator Expr
  795.     | Expr Operator
  796.     | Expr [ Exprs ]
  797.     | ( Expr )
  798.     | Number
  799.     | String
  800.     | TargetCode
  801.     | Ident :: Ident
  802.  
  803.  
  804. The semantics of the different kinds of expressions is as follows:
  805.  
  806. -    A node type creates a tree node and provides the children and  attributes
  807.      of  this node with the values given in parenthesis.  Again a missing list
  808.      in parentheses is treated as (..).
  809.  
  810. -    NIL represents the value NoTree or NIL.
  811.  
  812. -    A label refers to the expression it was bound to upon its definition.
  813.  
  814. -    A function or predicate call must be compatible  with  the  corresponding
  815.      definition in terms of the numbers of expressions and patterns as well as
  816.      their types.  A function call evaluates the expressions corresponding  to
  817.      input  parameters,  passes  the results to the function, and executes the
  818.      function. Upon return from the function the result value of the  function
  819.      determines  the  result  of  this  expression.   The values of the output
  820.      parameters that the function returns are matched against the actual  pat-
  821.      terns  of  the function call.  If one pair does not match the call fails.
  822.      Labels in the patterns may establish bindings that enable to refer to the
  823.      output parameters or subtrees thereof.
  824.  
  825. -    The don't care symbols specify that no computation  should  be  executed,
  826.      either  for  one  or for several expressions. The result values are unde-
  827.      fined.
  828.  
  829. -    The most common binary and unary operators (prefix and  postfix)  of  the
  830.      target  language  as  well as array indexing and parentheses are known to
  831.      puma.  They are passed unchanged to the output.
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.                                      Puma                                   12
  843.  
  844.  
  845. -    A target code expression, a number, or a string is evaluated  as  in  the
  846.      target language.
  847.  
  848. -    The construct Ident :: Ident can be used to refer to children  or  attri-
  849.      butes that are not matched by a label. This can be of interest because of
  850.      notational brevity or because matching is impossible. The reason for  the
  851.      latter  case can arise when a subset of a tree definition is presented to
  852.      puma using the concept of views. The first identifier is a label that  is
  853.      bound  to a tree (node).  The second identifier is the name of a child or
  854.      of an attribute of this node type.
  855.  
  856. In case of node types, labels for tree values, and  functions  returning  tree
  857. values,  puma  does  type checking. For user types, target code expressions or
  858. target operators no type checking is done by puma but (hopefully) later by the
  859. compiler.  An  expression  that  does  not  contain calls of puma functions or
  860. predicates always succeeds. An expression containing those calls  succeeds  if
  861. all the calls succeed - otherwise it fails.
  862.  
  863.     Examples:
  864.     Binary                      /* a node composition */
  865.     Tree.Binary                 /* a node composition */
  866.     Binary (X, Y, Z)            /* a node composition */
  867.     NIL
  868.     X
  869.     ResultType (t1, t2)         /* a function call */
  870.     _
  871.     k + 2
  872.     - k
  873.     k ++
  874.     a [x]
  875.     ({ Times })                 /* a named constant */
  876.     3.14
  877.     "abc"
  878.  
  879.  
  880. 3.10.  Statements
  881.  
  882. Statements are used to describe  conditions,  to  perform  output,  to  assign
  883. values  to  attributes,  and  to  control the execution of the transformer via
  884. recursive subroutine calls. A statement is either a condition  denoted  by  an
  885. expression,  a  call of a procedure, an assignment, one of the keywords REJECT
  886. or FAIL, a String or the keyword NL, a target code statement, or  declarations
  887. of  variables. Named arguments are not allowed in calls.  Every kind of state-
  888. ment may succeed or fail as described below.
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.                                      Puma                                   13
  908.  
  909.  
  910.     Syntax:
  911.     Statement =
  912.     | Expr
  913.     | Expr ( [ Exprs ] [ => Patterns ] )
  914.     | Expr := Expr
  915.     | REJECT
  916.     | FAIL
  917.     | String
  918.     | NL
  919.     | TargetCode
  920.     | Declarations
  921.     Declarations = Ident : Type { , Ident : Type }
  922.  
  923.  
  924.      There are some syntactic ambiguities: Target code in curly brackets  {  }
  925. is  considered  as target code statement instead of as target code expression.
  926. To obtain the latter meaning the expression should be enclosed in  parentheses
  927. (  ).  Subroutine calls are treated according to their declaration: Predicates
  928. and functions are treated as conditions, procedures and  external  subroutines
  929. are  treated as procedure calls.  If external subroutines should be considered
  930. as expressions, the call should be enclosed in parentheses ( ), too.  A string
  931. is  considered  as  a special kind of statement instead of as a normal expres-
  932. sion.
  933.  
  934. -    Conditions are denoted by expressions and can be used to  determine  pro-
  935.      perties  that  can not be expressed with pattern matching alone. Patterns
  936.      describe either shapes of a fixed size of a tree or the equality  between
  937.      two  values.  Properties of trees of unlimited size and relations like <,
  938.      <= etc. have to be checked with conditions.  The expression has to be  of
  939.      type  boolean  or  the  call of a predicate.  A condition succeeds if the
  940.      expression evaluates to true - otherwise it fails.
  941.  
  942. -    For a procedure call the same rules as for a  function  call  apply.   It
  943.      succeeds  if  the  values  of  all  output  parameters are matched by the
  944.      corresponding patterns - otherwise it fails.  A call of an undefined sub-
  945.      routine is treated as a call of a procedure that is either defined exter-
  946.      nally or in the GLOBAL target code section. Such a call is flagged  by  a
  947.      warning message.
  948.  
  949. -    An assignment statement evaluates its expression and stores this value at
  950.      the  entity denoted by the identifier on the left-hand side. The identif-
  951.      ier can denote
  952.  
  953.          a global or a local variable,
  954.          an input or an output parameter, or
  955.          a label for an attribute or a subtree.
  956.  
  957.      An assignment statement succeeds if the expression succeeds  -  otherwise
  958.      it fails.
  959.  
  960. -    The statement REJECT does nothing but fail. This way the execution of the
  961.      current rule terminates and control is passed to the next rule.
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.                                      Puma                                   14
  973.  
  974.  
  975. -    The statement FAIL causes the execution of the current subroutine to ter-
  976.      minate.  This  statement  is  allowed in procedures and predicates, only.
  977.      Depending on the kind of subroutine the following happens:
  978.  
  979.          A procedure terminates.
  980.          A predicate returns false.
  981.  
  982.  
  983. -    A string is an output statement that prints this  string.   (For  details
  984.      see section 3.13.).
  985.  
  986. -    The keyword NL is an output statement that prints  a  newline  character.
  987.      (For details see section 3.13.).
  988.  
  989. -    A target code statement is executed as in the target language. It can  be
  990.      used  for arbitrary actions. In particular it can compute the value of an
  991.      explicitly declared label (variable) by means of implementation  language
  992.      code  or  calls  of  external subroutines. A target code statement always
  993.      succeeds.
  994.  
  995. -    A declaration explicitly introduces a label or variable. It is similar to
  996.      a  label  in a pattern except that its value is undefined. It can be used
  997.      also for the definition of temporary variables. The user  is  responsible
  998.      that  all  labels  receive values either by assignments or by target code
  999.      statements. Declarations always succeed.
  1000.  
  1001.      Note, statements and expressions may cause side effects by changing e. g.
  1002. global  variables,  local  variables,  the input tree, or by producing output.
  1003. Those side effects are not undone when a rule fails.
  1004.  
  1005.     Examples:
  1006.     IsCompatible (t1, t2)        /* condition: predicate call         */
  1007.     (IsSimpleType (t))           /* condition: external  call         */
  1008.     X < Y                        /* condition: expression             */
  1009.     ({ X < Y })                  /* condition: target code expression */
  1010.     Code (Then)                  /* procedure call: internal          */
  1011.     printf ("hello")             /* procedure call: external          */
  1012.     X := Y
  1013.     { X = Y; }
  1014.     REJECT
  1015.     FAIL
  1016.     "hello"
  1017.     NL
  1018.     { Code (Then); }             /* unchecked internal call           */
  1019.     { printf ("hello"); }        /* unchecked external call           */
  1020.     Z: Expr
  1021.     { Z = mBinary (X, Y, Plus); }
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.                                      Puma                                   15
  1038.  
  1039.  
  1040. 3.11.  Equality Operations
  1041.  
  1042. The equality between two trees is defined recursively: Two trees are equal  if
  1043. the  node types of the two root nodes are equal and all corresponding subtrees
  1044. or attributes are equal.
  1045.  
  1046.      The equality between attribute values is type specific.  For  every  type
  1047. name  a  separate  equality test is defined.  Chosing different type names for
  1048. one type introduces subtypes and allows to treat attributes of different  sub-
  1049. types  differently.  The equality tests are defined by a macro mechanism using
  1050. the C preprocessor cpp:
  1051.  
  1052.     # define equalTYPE(a, b) a == b
  1053.  
  1054.  
  1055. TYPE is replaced by the concrete type name.  a and b are formal macro  parame-
  1056. ters referring to the attributes to be compared.
  1057.  
  1058.      The equality test for the predefined  types  of  a  target  language  are
  1059. predefined  within  puma  (see Appendix 3). For user-defined types, by default
  1060. the following equality test is used:
  1061.  
  1062.     in C:
  1063.     # define equalTYPE(a, b) memcmp ((char *) & a, (char *) & b, sizeof (a)) == 0
  1064.     in Modula-2:
  1065.     # define equalTYPE(a, b) yyIsEqual (a, b)
  1066.  
  1067.  
  1068. Above procedures check  values  of  arbitrary  types  by  comparing  the  byte
  1069. sequences.
  1070.  
  1071.      It is possible to redefine the operations by including new macro  defini-
  1072. tions in the GLOBAL section. The following example demonstrates the syntax for
  1073. doing this.
  1074.  
  1075.     Example in C:
  1076.     GLOBAL {
  1077.     typedef struct { short Line, Column; } tPosition;
  1078.     # define equaltPosition(a, b) a.Line == b.Line && a.Column == b.Column
  1079.     }
  1080.  
  1081.  
  1082.     Example in Modula-2:
  1083.     GLOBAL {
  1084.     TYPE tPosition = RECORD Line, Column: SHORTCARD; END;
  1085.     # define equaltPosition(a, b) (a.Line = b.Line) AND (a.Column = b.Column)
  1086.     }
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.                                      Puma                                   16
  1101.  
  1102.  
  1103. 3.12.  Begin Operations
  1104.  
  1105. Usually, a composition of a node specifies values for the attributes and chil-
  1106. dren.  Using dont't care symbols it is possible to omit these values.  In this
  1107. case the attributes and children are initialized by a  macro  mechanism  using
  1108. the C preprocessor cpp:
  1109.  
  1110.     # define beginTYPE(a)
  1111.  
  1112.  
  1113. TYPE is replaced by the concrete type name.  a is the formal  macro  parameter
  1114. referring to the attribute or children to be initialized.
  1115.  
  1116.      Initialization for attributes is predefined within puma by empty  macros.
  1117. Children are set to NULL or NIL, by default:
  1118.  
  1119.     in C:
  1120.     # define begintTYPE(a) a = NULL;
  1121.     in Modula-2:
  1122.     # define begintTYPE(a) a := NIL;
  1123.  
  1124.  
  1125.      It is possible to redefine the operations by including new macro  defini-
  1126. tions in the GLOBAL section. The following example demonstrates the syntax for
  1127. doing this.
  1128.  
  1129.     Example in C:
  1130.     GLOBAL {# define equaltint(a) a = 0;}
  1131.  
  1132.  
  1133.     Example in Modula-2:
  1134.     GLOBAL {# define equaltINTEGER(a) a := 0;}
  1135.  
  1136.  
  1137. 3.13.  Output Statements
  1138.  
  1139. The two builtin output statements "string" and NL are  translated  into  macro
  1140. calls:
  1141.  
  1142.     yyWrite ("string");
  1143.     yyWriteNl;
  1144.  
  1145. The macros are predefined as follows:
  1146.  
  1147.     in C:
  1148.     # define yyWrite(s) (void) fputs (s, yyf)
  1149.     # define yyWriteNl  (void) fputc ('\n', yyf)
  1150.     static FILE * yyf = stdout;
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.                                      Puma                                   17
  1163.  
  1164.  
  1165.     in Modula-2:
  1166.     # define yyWrite(s) IO.WriteS (yyf, s)
  1167.     # define yyWriteNl  IO.WriteNl (yyf)
  1168.     VAR yyf: IO.tFile;
  1169.     yyf := IO.StdOutput;
  1170.  
  1171. By default the statements print on standard output using the library  routines
  1172. specified in the macro definitions. This behaviour can be changed in two ways:
  1173. The global variable yyf can be assigned a new value that  describes  an  arbi-
  1174. trary file.  The macros can be redefined in the GLOBAL target code section.
  1175.  
  1176. 4.  Scopes
  1177.  
  1178. Scopes are regions of text which control the meaning of  identifiers.  A  puma
  1179. specification defines three kinds of scopes which are nested in each other:
  1180.  
  1181. global scope
  1182.      A complete puma specification defines a global scope.   It  contains  all
  1183.      declarations  included  in the GLOBAL target code section and all subrou-
  1184.      tine definitions. The subroutines can be defined in any order.
  1185.  
  1186. local scope
  1187.      Every subroutine definition introduces a local  scope.  It  contains  the
  1188.      names of the input and output parameters and the declarations included in
  1189.      a LOCAL target code section.
  1190.  
  1191. rule scope
  1192.      Every rule introduces a rule scope. It contains the labels used  in  this
  1193.      rule.  Labels are declared upon their first occurrence in patterns.  They
  1194.      are visible only within a rule.  Labels in  expressions  represent  using
  1195.      positions.  Labels have to be declared or bound textually before they are
  1196.      used.
  1197.  
  1198. For entities other then subroutine names and label names the  scope  rules  of
  1199. the target language apply.
  1200.  
  1201. 5.  Output
  1202.  
  1203. From a given specification, puma generates a program module in one of the tar-
  1204. get  languages C or Modula-2 implementing the desired transformation. The sub-
  1205. routines in the sense  of  puma  are  mapped  to  subroutines  in  the  target
  1206. language. Procedures yield procedures, functions yield functions that return a
  1207. value, and predicates yield boolean functions. These subroutines can be called
  1208. from  other  modules  using  the  usual  subroutine  call syntax of the target
  1209. language provided they are exported: All arguments are separated by  commas  -
  1210. the symbol => as separator between input and output arguments is only required
  1211. in calls processed by puma.
  1212.  
  1213.      The types of the parameters are treated as follows: Predefined  types  or
  1214. user  defined  types  remain  unchanged.  Node types or sets of node types are
  1215. replaced by the name of the corresponding tree type.  This is a pointer  to  a
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.                                      Puma                                   18
  1227.  
  1228.  
  1229. union of record types. Input parameters are passed by value and output parame-
  1230. ters are passed by reference (VAR in Modula-2) by  default.  Input  parameters
  1231. with the keyword REF are passed by reference, too.
  1232.  
  1233.      In addition to the exported subroutines, a puma generated module  exports
  1234. the  subroutines  BeginTRAFO  and  CloseTRAFO,  where TRAFO is replaced by the
  1235. module name. Both subroutines contain  the  target  code  sections  BEGIN  and
  1236. CLOSE.  All  target  code sections and target code representing expressions or
  1237. statements are more or less copied unchecked and unchanged  to  the  generated
  1238. output module. The only change is that in target code representing expressions
  1239. or statements label identifiers are replaced by access paths to the associated
  1240. values.
  1241.  
  1242.      The rules of a subroutine are treated like a comfortable case  or  switch
  1243. statement.   The  code generated for pattern matching is relatively simple.  A
  1244. naive implementation would just use a sequence of if statements.  This kind of
  1245. code  showed  to  be already rather efficient.  Possible optimizations are the
  1246. clever use of switch statements and the elimination of common  subexpressions.
  1247. Furthermore, tail recursion can be turned into iteration.  Labels are replaced
  1248. by access paths to the associated values.  The code for  the  construction  of
  1249. tree  nodes  is  inserted  in-line.  It is therefore efficient because no pro-
  1250. cedure calls are necessary for the creation  of  tree  nodes.   Moreover,  the
  1251. transformer module independent of the tree module with respect to the presence
  1252. of procedures to create nodes and the classification of input attributes.
  1253.  
  1254. 6.  Usage
  1255.  
  1256. NAME
  1257.    puma - a generator for the transformation of attributed trees
  1258. SYNOPSIS
  1259.    puma [-options] [-l dir] [file]
  1260. DESCRIPTION
  1261.    puma is a tool for the transformation of attributed trees which is based on
  1262.    pattern  matching  and unification.  It generates transformers (named Trafo
  1263.    by default) that map attributed trees to arbitrary  output.  As  this  tool
  1264.    also  has  to know about the structure of the tree this information is com-
  1265.    municated from ast to puma via a file with the suffix .TS. If file is omit-
  1266.    ted the specification is read from standard input.
  1267. OPTIONS
  1268.  
  1269. a    generate all, same as -di (default)
  1270.  
  1271. d    generate definition module
  1272.  
  1273. i    generate implementation module
  1274.  
  1275. s    suppress warnings
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.                                      Puma                                   19
  1289.  
  1290.  
  1291. m    use procedure MakeTREE to construct nodes (default is in-line code)
  1292.  
  1293. p    allow node constructors without parentheses
  1294.  
  1295. f    signal a runtime error if none of the rules of a procedure matches
  1296.  
  1297. k    allow non-linear patterns
  1298.  
  1299. n    check parameters for NoTREE (NIL) and treat as failure (tg compatibility)
  1300.  
  1301. w    surround actions by WITH statements (tg compatibility)
  1302.  
  1303. e    treat undefined names as error
  1304.  
  1305. v    treat undefined names as warning
  1306.  
  1307. o    list undefined names on standard output
  1308.  
  1309. t    print tree definitions
  1310.  
  1311. r    print patterns
  1312.  
  1313. q    browse internal data structure
  1314.  
  1315. 6    generate # line directives
  1316.  
  1317. 7    touch output files only if necessary
  1318.  
  1319. 8    report storage consumption
  1320.  
  1321. c    generate C code (default is Modula-2)
  1322.  
  1323. h    print help information
  1324.  
  1325. -ldir
  1326.      dir is the directory where puma finds its table files
  1327.   FILES
  1328.      <tree>.TS           description of the tree grammar(s)
  1329.      if output is in C:
  1330.      <module>.h          specification of the generated transformer module
  1331.      <module>.c          body of the generated transformer module
  1332.      if output is in Modula-2:
  1333.      <module>.md         definition module of the generated transformer module
  1334.      <module>.mi         implementation module of the generated transformer module
  1335.   SEE ALSO
  1336.      J. Grosch: "Puma - A  Generator  for  the  Transformation  of  Attributed
  1337.      Trees", GMD Forschungsstelle an der Universitaet Karlsruhe, Compiler Gen-
  1338.      eration Report No. 26
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.                                      Puma                                   20
  1350.  
  1351.  
  1352.      J. Grosch: "Transformation of Attributed Trees Using  Pattern  Matching",
  1353.      GMD  Forschungsstelle  an der Universitaet Karlsruhe, Compiler Generation
  1354.      Report No. 27
  1355.  
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.                                      Puma                                   21
  1415.  
  1416.  
  1417. Appendix 1: Syntax Summary
  1418.  
  1419.  
  1420. /* parser grammar */
  1421.  
  1422. Trafo           = TrafoName TreePart PublicPart ExternPart0 TargetCodes
  1423.                      Subroutines .
  1424.  
  1425. TrafoName       = <
  1426.                 = .
  1427.                 = TRAFO Name .
  1428. > .
  1429. TreePart        = <
  1430.                 = .
  1431.                 = 'TREE' TreeNames .
  1432. > .
  1433. TreeNames       = <
  1434.                 = .
  1435.                 = TreeNames ',' .
  1436.                 = TreeNames Name .
  1437. > .
  1438. PublicPart      = <
  1439.                 = .
  1440.                 = PUBLIC Names .
  1441. > .
  1442. ExternPart0     = <
  1443.                 = .
  1444.                 = EXTERN Names OptSemiColon .
  1445. > .
  1446. ExternPart      = <
  1447.                 = .
  1448.                 = EXTERN Names ';' .
  1449. > .
  1450. Names           = <
  1451.                 = .
  1452.                 = Names ',' .
  1453.                 = Names Name .
  1454. > .
  1455. TargetCodes     = <
  1456.                 = .
  1457.                 = TargetCodes 'EXPORT' TargetCode .
  1458.                 = TargetCodes 'IMPORT' TargetCode .
  1459.                 = TargetCodes 'GLOBAL' TargetCode .
  1460.                 = TargetCodes 'BEGIN'  TargetCode .
  1461.                 = TargetCodes 'CLOSE'  TargetCode .
  1462. > .
  1463. Subroutines     = <
  1464.                 = .
  1465.                 = Subroutines PROCEDURE Name '(' Parameters OutParameters ')'
  1466.                      ExternPart LocalCode Rules .
  1467.                 = Subroutines 'FUNCTION' Name '(' Parameters OutParameters ')'
  1468.                      Type ExternPart LocalCode Rules .
  1469.                 = Subroutines PREDICATE Name '(' Parameters OutParameters ')'
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.                                      Puma                                   22
  1481.  
  1482.  
  1483.                      ExternPart LocalCode Rules .
  1484. > .
  1485. OutParameters   = <
  1486.                 = .
  1487.                 = '=>' Parameters .
  1488. > .
  1489. Parameters      = <
  1490.                 = .
  1491.                 = Mode Ident ':' Type .
  1492.                 = Mode Type .
  1493.                 = Mode Ident ':' Type ',' Parameters .
  1494.                 = Mode Type ',' Parameters .
  1495. > .
  1496. Mode            = <
  1497.                 = .
  1498.                 = REF .
  1499. > .
  1500. Declarations    = <
  1501.                 = Ident ':' Type .
  1502.                 = Ident ':' Type ',' Declarations .
  1503. > .
  1504. Type            = <
  1505.                 = Ident .
  1506.                 = Ident '.' Name .
  1507.                 = '[' Names ']' .
  1508.                 = Ident '.' '[' Names ']' .
  1509. > .
  1510. LocalCode       = <
  1511.                 = .
  1512.                 = 'LOCAL' TargetCode .
  1513. > .
  1514. Rules           = <
  1515.                 = .
  1516.                 = Rules Patterns2 '.' .
  1517.                 = Rules Patterns '?' Statements '.' .
  1518.                 = Rules Patterns '=>' Exprs2 '.' .
  1519.                 = Rules Patterns RETURN Expr ';' '.' .
  1520.                 = Rules Patterns '=>' Exprs '?' Statements '.' .
  1521.                 = Rules Patterns '?' Statements '=>' Exprs2 '.' .
  1522.                 = Rules Patterns '=>' Exprs RETURN Expr ';' '.' .
  1523.                 = Rules Patterns RETURN Expr OptSemiColon '?' Statements '.' .
  1524.                 = Rules Patterns '?' Statements RETURN Expr ';' '.' .
  1525.                 = Rules Patterns '=>' Exprs RETURN Expr OptSemiColon '?'
  1526.                      Statements '.' .
  1527.                 = Rules Patterns '=>' Exprs '?' Statements RETURN Expr ';' '.' .
  1528.                 = Rules Patterns '?' Statements '=>' Exprs RETURN Expr ';' '.' .
  1529. > .
  1530. OptSemiColon    = <
  1531.                 = .
  1532.                 = ';' .
  1533. > .
  1534. Patterns        = <
  1535.                 = Exprs .
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.                                      Puma                                   23
  1547.  
  1548.  
  1549.                 = Exprs ';' Patterns .
  1550. > .
  1551. Patterns2       = <
  1552.                 = Exprs ';' .
  1553.                 = Exprs ';' Patterns2 .
  1554. > .
  1555. Exprs           = <
  1556.                 = '..' .
  1557.                 = '..' ',' .
  1558.                 = Expr .
  1559.                 = Expr ',' Exprs .
  1560.                 = NamedExprs .
  1561. > .
  1562. NamedExprs      = <
  1563.                 = .
  1564.                 = Ident ':=' Expr .
  1565.                 = Ident ':=' Expr ',' NamedExprs .
  1566. > .
  1567. Exprs2          = <
  1568.                 = '..' .
  1569.                 = '..' ',' .
  1570.                 = Expr ',' Exprs2 .
  1571.                 = NamedExprs2 .
  1572. > .
  1573. NamedExprs2     = <
  1574.                 = .
  1575.                 = Ident ':=' Expr ',' NamedExprs2 .
  1576. > .
  1577. Expr            = <
  1578.                 = PrefixExpr .
  1579.                 = Expr Operator PrefixExpr .
  1580. > .
  1581. PrefixExpr      = <
  1582.                 = PostfixExpr .
  1583.                 = Ident ':' PostfixExpr .
  1584.                 = Ident ':>' PostfixExpr .
  1585.                 = Operator PrefixExpr .
  1586.                 = IncOperator PrefixExpr .
  1587. > .
  1588. PostfixExpr     = <
  1589.                 = PrimaryExpr .
  1590.                 = PostfixExpr '[' Exprs ']' .
  1591.                 = PostfixExpr '(' Exprs ')' .
  1592.                 = PostfixExpr '(' Exprs '=>' Exprs ')' .
  1593.                 = PostfixExpr '.' Ident .
  1594.                 = PostfixExpr '->' Ident .
  1595.                 = PostfixExpr '^' .
  1596.                 = PostfixExpr IncOperator .
  1597. > .
  1598. PrimaryExpr     = <
  1599.                 = Ident .
  1600.                 = NIL .
  1601.                 = '_' .
  1602.  
  1603.  
  1604.  
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.                                      Puma                                   24
  1613.  
  1614.  
  1615.                 = Number .
  1616.                 = String .
  1617.                 = Ident '::' Ident .
  1618.                 = '{' TargetCodes2 '}' .
  1619.                 = '(' Expr ')' .
  1620. > .
  1621. Statements      = <
  1622.                 = .
  1623.                 = Statements Expr ';' .
  1624.                 = Statements Expr ':=' Expr ';' .
  1625.                 = Statements REJECT .
  1626.                 = Statements FAIL .
  1627.                 = Statements NL .
  1628.                 = Statements Declarations ';' .
  1629.                 = Statements '{' TargetCodes2 '}' ';' .
  1630.                 = Statements ';' .
  1631. > .
  1632. TargetCodes2    = <
  1633.                 = .
  1634.                 = TargetCodes2 Name Space '::' Space Ident .
  1635.                 = TargetCodes2 Name Space '::' Space .
  1636.                 = TargetCodes2 Name Space .
  1637.                 = TargetCodes2 '::' .
  1638.                 = TargetCodes2 TargetCode2 .
  1639.                 = TargetCodes2 WhiteSpace .
  1640. > .
  1641. Name            = <
  1642.                 = Ident .
  1643.                 = String .
  1644. > .
  1645. Space           = <
  1646.                 = .
  1647.                 = Space WhiteSpace .
  1648. > .
  1649.  
  1650. /* lexical grammar */
  1651.  
  1652. Ident           : <
  1653.                 = Letter .
  1654.                 = `_` .
  1655.                 = Ident Letter .
  1656.                 = Ident Digit .
  1657.                 = Ident '_' .
  1658. > .
  1659. Number          : <
  1660.                 = Integer .
  1661.                 = Real .
  1662. > .
  1663. Integer         : <
  1664.                 = Digit .
  1665.                 = Integer Digit .
  1666. > .
  1667. Real            : <
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.                                      Puma                                   25
  1679.  
  1680.  
  1681.                 = Integer '.' Integer Exponent .
  1682.                 = Integer '.' Exponent .
  1683.                 = '.' Integer Exponent .
  1684. > .
  1685. Exponent        : <
  1686.                 = .
  1687.                 = `E` `+` Integer .
  1688.                 = `E` `-` Integer .
  1689.                 = `E` Integer .
  1690. > .
  1691. String          : <
  1692.                 = "'" Characters "'" .
  1693.                 = '"' Characters '"' .
  1694. > .
  1695. TargetCode      : '{' Characters '}' .
  1696.  
  1697. TargetCode2     : Characters .
  1698.  
  1699. WhiteSpace      : <
  1700.                 = ' ' .
  1701.                 = Tabulator .
  1702.                 = Newline .
  1703. > .
  1704.  
  1705. Operator        : <
  1706.                 = '!' .
  1707.                 = '!=' .
  1708.                 = '#' .
  1709.                 = '%' .
  1710.                 = '&' .
  1711.                 = '&&' .
  1712.                 = '*' .
  1713.                 = '+' .
  1714.                 = '-' .
  1715.                 = '/' .
  1716.                 = '<' .
  1717.                 = '<<' .
  1718.                 = '<=' .
  1719.                 = '<>' .
  1720.                 = '=' .
  1721.                 = '==' .
  1722.                 = '>' .
  1723.                 = '>=' .
  1724.                 = '>>' .
  1725.                 = '|' .
  1726.                 = '||' .
  1727.                 = '~' .
  1728.                 = AND .
  1729.                 = DIV .
  1730.                 = IN .
  1731.                 = MOD .
  1732.                 = NOT .
  1733.                 = OR .
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.                                      Puma                                   26
  1745.  
  1746.  
  1747.                 = '\' Characters WhiteSpace .
  1748. > .
  1749. IncOperator     : <
  1750.                 = '++' .
  1751.                 = '--' .
  1752. > .
  1753.  
  1754. Comment         : '/*' Characters '*/' .
  1755.  
  1756. Characters      : <
  1757.                 = .
  1758.                 = Characters Character .
  1759. > .
  1760.  
  1761. /* replacements */
  1762.  
  1763. '..'            : < = '...' .  > .
  1764. '?'             : < = ':-'  .  > .
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792.  
  1793.  
  1794.  
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804.  
  1805.  
  1806.  
  1807.  
  1808.  
  1809.                                      Puma                                   27
  1810.  
  1811.  
  1812. Appendix 2: Examples from MiniLAX
  1813.  
  1814. The following examples are taken from a compiler for the demo  language  Mini-
  1815. LAX. The complete MiniLAX example can be found in [Gro90]:
  1816.  
  1817.      The first part contains the abstract syntax of the language and the  out-
  1818. put  attributes  which  are  assumed  to  be  computed by a preceding semantic
  1819. analysis phase. This information describes the structure of  the  input  to  a
  1820. puma generated transformer. It is written in the input language of ast.
  1821.  
  1822.      The second part  specifies  the  generation  of  intermediate  code.  The
  1823. abstract syntax tree is mapped to I-Code which is a subset of P-Code.
  1824.  
  1825.      The third part specifies routines to handle types. Types  are  internally
  1826. represented  by  trees.  The  routines are used by the semantic analysis phase
  1827. which is implemented by an attribute grammar.
  1828.  
  1829. Appendix 2.1: Abstract Syntax
  1830.  
  1831. MODULE AbstractSyntax /* ------------------------------------------ */
  1832.  
  1833. TREE EXPORT  {
  1834. # include "Idents.h"
  1835. # include "Positions.h"
  1836. }
  1837.  
  1838. GLOBAL  {
  1839. # include "Idents.h"
  1840. # include "Positions.h"
  1841. # include <stdio.h>
  1842. }
  1843.  
  1844. EVAL Semantics
  1845.  
  1846. PROPERTY INPUT
  1847.  
  1848. RULE
  1849.  
  1850. MiniLAX         = Proc .
  1851. Decls           = <
  1852.    NoDecl       = .
  1853.    Decl         = Next: Decls REV [Ident: tIdent] [Pos: tPosition] <
  1854.       Var       = Type .
  1855.       Proc      = Formals Decls Stats .
  1856.    >.
  1857. >.
  1858. Formals         = <
  1859.    NoFormal     = .
  1860.    Formal       = Next: Formals REV [Ident: tIdent] [Pos: tPosition] Type .
  1861. >.
  1862. Type            = <
  1863.    Integer      = .
  1864.    Real         = .
  1865.  
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.  
  1873.  
  1874.  
  1875.                                      Puma                                   28
  1876.  
  1877.  
  1878.    Boolean      = .
  1879.    Array        = Type OUT            [Lwb] [Upb] [Pos: tPosition] .
  1880.    Ref          = Type OUT .
  1881.    NoType       = .
  1882.    ErrorType    = .
  1883. >.
  1884. Stats           = <
  1885.    NoStat       = .
  1886.    Stat         = Next: Stats REV <
  1887.       Assign    = Adr Expr            [Pos: tPosition] .
  1888.       Call      = Actuals             [Ident: tIdent] [Pos: tPosition] .
  1889.       If        = Expr Then: Stats Else: Stats .
  1890.       While     = Expr Stats .
  1891.       Read      = Adr .
  1892.       Write     = Expr .
  1893.    >.
  1894. >.
  1895. Actuals         = <
  1896.    NoActual     =                     [Pos: tPosition OUT] .
  1897.    Actual       = Next: Actuals REV Expr .
  1898. >.
  1899. Expr            =                     [Pos: tPosition] <
  1900.    Binary       = Lop: Expr Rop: Expr [Operator: short] .
  1901.    Unary        = Expr                [Operator: short] .
  1902.    IntConst     =                     [Value         OUT] .
  1903.    RealConst    =                     [Value: double OUT] .
  1904.    BoolConst    =                     [Value: bool   OUT] .
  1905.    Adr          = <
  1906.       Index     = Adr Expr .
  1907.       Ident     =                     [Ident: tIdent] .
  1908.    >.
  1909. >.
  1910. Coercions       = <
  1911.    NoCoercion   = .
  1912.    Coercion     = Next: Coercions OUT <
  1913.       Content   = .             /* fetch contents of location    */
  1914.       IntToReal = .             /* convert integer value to real */
  1915.    >.
  1916. >.
  1917.  
  1918. END AbstractSyntax
  1919.  
  1920. MODULE Output /* -------------------------------------------------- */
  1921.  
  1922. PROPERTY OUTPUT
  1923.  
  1924. DECLARE
  1925.    Formals Decls        = [Decls: tObjects THREAD] .
  1926.    Call Ident           = [Object: tObjects] [level: short] .
  1927.    If While             = [Label1] [Label2] .
  1928.    Read Write Binary    = [TypeCode: short] .
  1929.    Expr                 = Type Co: Coercions .
  1930.    Index                = type: Type .
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.                                      Puma                                   29
  1942.  
  1943.  
  1944. END Output
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.  
  1994.  
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.  
  2003.  
  2004.  
  2005.  
  2006.                                      Puma                                   30
  2007.  
  2008.  
  2009. Appendix 2.2: Generation of Intermediate Code
  2010.  
  2011.  
  2012. TRAFO ICode TREE Tree Definitions PUBLIC Code
  2013.  
  2014. EXTERN
  2015.    ADD BoolType CHK ENT Emit EmitReal FJP FLT FalseCode INV IXA IntType JMP JSR
  2016.    LDA LDC LDI LES MST MUL REA RET RealType STI SUB TrueCode TypeSize WRI
  2017.  
  2018. GLOBAL {
  2019. # include "Tree.h"
  2020. # include "Definitions.h"
  2021. # include "Types.h"
  2022. # include "ICodeInter.h"
  2023. }
  2024.  
  2025. PROCEDURE Code (t: Tree)
  2026.  
  2027. MiniLax (Proc) ?
  2028.         Code (Proc);
  2029.         .
  2030. Proc (Next := Next:Decls (Proc3 (ParSize := ParSize, DataSize := DataSize), ..),
  2031.                 Decls := Decls, Stats := Stats) ?
  2032.         Emit (ENT, DataSize - ParSize, 0);
  2033.         Code (Stats);
  2034.         Emit (RET, 0, 0);
  2035.         Code (Decls);
  2036.         Code (Next);
  2037.         .
  2038. Var (Next := Next) ?
  2039.         Code (Next);
  2040.         .
  2041. Assign (Next, Adr, Expr, _) ?
  2042.         Code (Adr); Code (Adr::Co);
  2043.         Code (Expr); Code (Expr::Co);
  2044.         Emit (STI, 0, 0);
  2045.         Code (Next);
  2046.         .
  2047. Call (Next, Actuals, _, _, Proc3 (Level := Level, Label := Label,
  2048.                 ParSize := ParSize), level) ?
  2049.         Emit (MST, level - Level, 0);
  2050.         Code (Actuals);
  2051.         Emit (JSR, ParSize - 3, Label);
  2052.         Code (Next);
  2053.         .
  2054. If (Next, Expr, Then, Else, Label1, Label2) ?
  2055.         Code (Expr); Code (Expr::Co);
  2056.         Emit (FJP, Label1, 0);
  2057.         Code (Then);
  2058.         Emit (JMP, Label2, 0);
  2059.         Code (Else);
  2060.         Code (Next);
  2061.         .
  2062.  
  2063.  
  2064.  
  2065.  
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.                                      Puma                                   31
  2073.  
  2074.  
  2075. While (Next, Expr, Stats, Label1, Label2) ?
  2076.         Emit (JMP, Label2, 0);
  2077.         Code (Stats);
  2078.         Code (Expr); Code (Expr::Co);
  2079.         Emit (INV, 0, 0);
  2080.         Emit (FJP, Label1, 0);
  2081.         Code (Next);
  2082.         .
  2083. Read (Next, Adr, TypeCode) ?
  2084.         Code (Adr); Code (Adr::Co);
  2085.         Emit (REA, TypeCode, 0);
  2086.         Emit (STI, 0, 0);
  2087.         Code (Next);
  2088.         .
  2089. Write (Next, Expr, TypeCode) ?
  2090.         Code (Expr); Code (Expr::Co);
  2091.         Emit (WRI, TypeCode, 0);
  2092.         Code (Next);
  2093.         .
  2094. Actual (Next, Expr) ?
  2095.         Code (Expr); Code (Expr::Co);
  2096.         Code (Next);
  2097.         .
  2098. Binary (_, _, _, Lop, Rop, {Times}, TypeCode) ?
  2099.         Code (Lop); Code (Lop::Co);
  2100.         Code (Rop); Code (Rop::Co);
  2101.         Emit (MUL, TypeCode, 0);
  2102.         .
  2103. Binary (_, _, _, Lop, Rop, {Plus}, TypeCode) ?
  2104.         Code (Lop); Code (Lop::Co);
  2105.         Code (Rop); Code (Rop::Co);
  2106.         Emit (ADD, TypeCode, 0);
  2107.         .
  2108. Binary (_, _, _, Lop, Rop, {Less}, TypeCode) ?
  2109.         Code (Lop); Code (Lop::Co);
  2110.         Code (Rop); Code (Rop::Co);
  2111.         Emit (LES, TypeCode, 0);
  2112.         .
  2113. Unary (Expr := Expr) ?
  2114.         Code (Expr); Code (Expr::Co);
  2115.         Emit (INV, 0, 0);
  2116.         .
  2117. IntConst  (Value := Value  ) ? Emit (LDC, IntType, Value); .
  2118. RealConst (Value := Value  ) ? EmitReal (LDC, RealType, Value); .
  2119. BoolConst (Value := {true} ) ? Emit (LDC, BoolType, TrueCode); .
  2120. BoolConst (Value := {false}) ? Emit (LDC, BoolType, FalseCode); .
  2121.  
  2122. Index (_, _, _, Adr, Expr, Array (Type, Lwb, Upb, _)) ?
  2123.         Code (Adr); Code (Adr::Co);
  2124.         Code (Expr); Code (Expr::Co);
  2125.         Emit (CHK, Lwb, Upb);
  2126.         Emit (LDC, IntType, Lwb);
  2127.         Emit (SUB, IntType, 0);
  2128.  
  2129.  
  2130.  
  2131.  
  2132.  
  2133.  
  2134.  
  2135.  
  2136.  
  2137.  
  2138.                                      Puma                                   32
  2139.  
  2140.  
  2141.         Emit (IXA, TypeSize (Type), 0);
  2142.         .
  2143. Ident (_, _, _, Ident, Var3 (Level := Level, Offset := Offset), level) ?
  2144.         Emit (LDA, level - Level, Offset);
  2145.         .
  2146. Content (Next) ?
  2147.         Emit (LDI, 0, 0);
  2148.         Code (Next);
  2149.         .
  2150. IntToReal (Next) ?
  2151.         Emit (FLT, 0, 0);
  2152.         Code (Next);
  2153.         .
  2154.  
  2155.  
  2156.  
  2157.  
  2158.  
  2159.  
  2160.  
  2161.  
  2162.  
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.  
  2177.  
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.  
  2184.  
  2185.  
  2186.  
  2187.  
  2188.  
  2189.  
  2190.  
  2191.  
  2192.  
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202.  
  2203.                                      Puma                                   33
  2204.  
  2205.  
  2206. Appendix 2.3: Procedures for Type Handling
  2207.  
  2208.  
  2209. TRAFO Types PUBLIC
  2210.  
  2211. Reduce                  /* return type without any ref levels           */
  2212.  
  2213. ReduceToRef             /* return type with ref level 1                 */
  2214.  
  2215. Reduce1                 /* return type with 1 ref level removed         */
  2216.  
  2217. RefLevel                /* return number of ref levels of a type        */
  2218.  
  2219. IsSimpleType            /* check whether a type is simple               */
  2220.  
  2221. IsCompatible            /* check whether two types are compatible       */
  2222.  
  2223. IsAssignmentCompatible  /* check whether two types are                  */
  2224.                         /* assignment compatible                        */
  2225.  
  2226. ResultType              /* return the type of the result of             */
  2227.                         /* applying an operator to two operands         */
  2228.  
  2229. CheckParams             /* check a formal list of parameters            */
  2230.                         /* against an actual list of parameters         */
  2231.  
  2232. GetElementType          /* return the type of the elements of           */
  2233.                         /* an array type                                */
  2234.  
  2235. TypeSize                /* return the number of bytes used for          */
  2236.                         /* the internal representation of an            */
  2237.                         /* object of a certain type                     */
  2238.  
  2239. Coerce                  /* returns the coercion necessary to convert    */
  2240.                         /* an object of type 't1' to type 't2'          */
  2241.  
  2242. EXTERN nBoolean Error nNoCoercion
  2243.  
  2244. GLOBAL {
  2245. # include "Errors.h"
  2246. # include "Positions.h"
  2247. # include "Tree.h"
  2248.  
  2249. # define Error(Text, Position) Message (Text, xxError, Position)
  2250.  
  2251. static tTree nBoolean, nNoType, nNoCoercion;
  2252. }
  2253.  
  2254. BEGIN {
  2255.    nBoolean     = mBoolean      ();
  2256.    nNoType      = mNoType       ();
  2257.    nNoCoercion  = mNoCoercion   ();
  2258. }
  2259.  
  2260.  
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.                                      Puma                                   34
  2270.  
  2271.  
  2272. FUNCTION Reduce (Type) Type
  2273.    Ref (t)      RETURN Reduce (t) ?.
  2274.    t            RETURN t ?.
  2275.  
  2276. FUNCTION ReduceToRef (Type) Type
  2277.    Ref (t:Ref)  RETURN ReduceToRef (t) ?.
  2278.    t:Ref        RETURN t ?.
  2279.    t            RETURN t ?.
  2280.  
  2281. FUNCTION Reduce1 (Type) Type
  2282.    Ref (t)      RETURN t ?.
  2283.    t            RETURN t ?.
  2284.  
  2285. FUNCTION RefLevel (Type) int
  2286.    Ref (t)      RETURN RefLevel (t) + 1 ?.
  2287.    _            RETURN 0 ?.
  2288.  
  2289. PREDICATE IsSimpleType (Type)
  2290.    Array        ? FAIL; .
  2291.    _            ?.
  2292.  
  2293. PREDICATE IsCompatible (Type, Type)
  2294.    Integer      , Integer       ?.
  2295.    Real         , Real          ?.
  2296.    Boolean      , Boolean       ?.
  2297.    Array (t1, Lwb, Upb, _), Array (t2, Lwb, Upb, _) ;
  2298.    Ref (t1)     , t2            ;
  2299.    t1           , Ref (t2)      ? IsCompatible (t1, t2); .
  2300.    NoType       , _             ?.
  2301.    _            , NoType        ?.
  2302.    ErrorType    , _             ?.
  2303.    _            , ErrorType     ?.
  2304.  
  2305. PREDICATE IsAssignmentCompatible (Type, Type)
  2306.    Integer      , Integer       ?.
  2307.    Real         , Real          ?.
  2308.    Real         , Integer       ?.
  2309.    Boolean      , Boolean       ?.
  2310.    Ref (t1)     , t2            ;
  2311.    t1           , Ref (t2)      ? IsAssignmentCompatible (t1, t2); .
  2312.    NoType       , _             ?.
  2313.    _            , NoType        ?.
  2314.    ErrorType    , _             ?.
  2315.    _            , ErrorType     ?.
  2316.  
  2317. FUNCTION ResultType (Type, Type, int) Type
  2318.    t:Integer    , Integer       , { Plus }      RETURN t        ?.
  2319.    t:Real       , Real          , { Plus }      RETURN t        ?.
  2320.    t:Integer    , Integer       , { Times }     RETURN t        ?.
  2321.    t:Real       , Real          , { Times }     RETURN t        ?.
  2322.    Integer      , Integer       , { Less }      RETURN nBoolean ?.
  2323.    Real         , Real          , { Less }      RETURN nBoolean ?.
  2324.    t:Boolean    , Boolean       , { Less }      RETURN t        ?.
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.                                      Puma                                   35
  2336.  
  2337.  
  2338.    t:Boolean    , _             , { Not }       RETURN t        ?.
  2339.    Ref (t1)     , t2            , o             ;
  2340.    t1           , Ref (t2)      , o             RETURN ResultType (t1, t2, o) ?.
  2341.    t:NoType     , _             , _             RETURN t        ?.
  2342.    _            , t:NoType      , _             RETURN t        ?.
  2343.    ErrorType    , _             , _             RETURN NoType   ?.
  2344.    _            , ErrorType     , _             RETURN NoType   ?.
  2345.    ..                                           RETURN ErrorType?.
  2346.  
  2347. PROCEDURE CheckParams (Actuals, Formals)
  2348.    NoActual     , NoFormal      ?.
  2349.    NoActual (Pos), _            ?
  2350.       Error ("too few actual parameters"        , Pos); .
  2351.    Actual (_, Expr (Pos, ..)), NoFormal ?
  2352.       Error ("too many actual parameters"       , Pos); .
  2353.  
  2354. /* alternative 1 */
  2355.  
  2356.    Actual (NextA, Expr (Pos, TypeA, ..)), Formal (_, _, NextF, _, _, TypeF) ?
  2357.       {
  2358.          if (! IsCompatible (TypeA, TypeF))
  2359.             Error ("parameter type incompatible", Pos);
  2360.          if (! (RefLevel (TypeF) - 1 <= RefLevel (TypeA)))
  2361.             Error ("variable required"          , Pos);
  2362.       };
  2363.       CheckParams (NextA, NextF); .
  2364.  
  2365. /* alternative 2 */
  2366.  
  2367.    Actual (NextA, Expr (Pos, TypeA, ..)), Formal (_, _, NextF, _, _, TypeF) ?
  2368.       ! IsCompatible (TypeA, TypeF);
  2369.       Error ("parameter type incompatible"      , Pos);
  2370.       REJECT; .
  2371.  
  2372.    Actual (NextA, Expr (Pos, TypeA, ..)), Formal (_, _, NextF, _, _, TypeF) ?
  2373.       ! (RefLevel (TypeF) - 1 <= RefLevel (TypeA));
  2374.       Error ("variable required"                , Pos);
  2375.       REJECT; .
  2376.  
  2377.    Actual (NextA, Expr (Pos, TypeA, ..)), Formal (_, _, NextF, _, _, TypeF) ?
  2378.       CheckParams (NextA, NextF); .
  2379.  
  2380. /* alternative 3 */
  2381.  
  2382.    Actual (NextA, Expr (Pos, TypeA, ..)), Formal (_, _, NextF, _, _, TypeF) ?
  2383.       CheckCompatible (Pos, TypeA, TypeF);
  2384.       CheckRefLevel (Pos, TypeA, TypeF);
  2385.       CheckParams (NextA, NextF); .
  2386.  
  2387. PROCEDURE CheckCompatible (tPosition, Type, Type)
  2388.    _    , t1    , t2    ? IsCompatible (t1, t2); .
  2389.    Pos  , ..            ? Error ("parameter type incompatible"  , Pos); .
  2390.  
  2391.  
  2392.  
  2393.  
  2394.  
  2395.  
  2396.  
  2397.  
  2398.  
  2399.  
  2400.                                      Puma                                   36
  2401.  
  2402.  
  2403. PROCEDURE CheckRefLevel (tPosition, Type, Type)
  2404.    _    , t1    , t2    ? RefLevel (t2) - 1 <= RefLevel (t1); .
  2405.    Pos  , ..            ? Error ("variable required"            , Pos); .
  2406.  
  2407. FUNCTION GetElementType (Type) Type
  2408.    Array (t, ..)        RETURN t ?.
  2409.    _                    RETURN NoType ?.
  2410.  
  2411. FUNCTION TypeSize (Type) int
  2412.    Array (t, Lwb, Upb, _)       RETURN (Upb - Lwb + 1) * TypeSize (t) ?.
  2413.    _                            RETURN 1 ?.
  2414.  
  2415. FUNCTION Coerce (t1: Type, t2: Type) Coercions
  2416.    Ref (T1)     , Ref (T2)      RETURN Coerce (T1, T2) ?.
  2417.    Integer      , Real          RETURN IntToReal (nNoCoercion) ?.
  2418.    Ref (T1)     , T2            RETURN Content (Coerce (T1, T2)) ?.
  2419.    ..                           RETURN nNoCoercion ?.
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.  
  2440.  
  2441.  
  2442.  
  2443.  
  2444.  
  2445.  
  2446.  
  2447.  
  2448.  
  2449.  
  2450.  
  2451.  
  2452.  
  2453.  
  2454.  
  2455.  
  2456.  
  2457.  
  2458.  
  2459.  
  2460.  
  2461.  
  2462.  
  2463.  
  2464.  
  2465.                                      Puma                                   37
  2466.  
  2467.  
  2468. Appendix 3: Equality Operations
  2469.  
  2470. Appendix 3.1: C
  2471.  
  2472. # define equalint(a, b)         a == b
  2473. # define equalshort(a, b)       a == b
  2474. # define equallong(a, b)        a == b
  2475. # define equalunsigned(a, b)    a == b
  2476. # define equalfloat(a, b)       a == b
  2477. # define equaldouble(a, b)      a == b
  2478. # define equalbool(a, b)        a == b
  2479. # define equalchar(a, b)        a == b
  2480. # define equaltString(a, b)     strcmp (a, b)
  2481. # define equaltStringRef(a, b)  a == b
  2482. # define equaltIdent(a, b)      a == b
  2483. # define equaltSet(a, b)        IsEqual (& a, & b)
  2484. # define equaltPosition(a, b)   Compare (a, b) == 0
  2485.  
  2486. Appendix 3.2: Modula-2
  2487.  
  2488. # define equalINTEGER(a, b)     a = b
  2489. # define equalSHORTINT(a, b)    a = b
  2490. # define equalLONGINT(a, b)     a = b
  2491. # define equalCARDINAL(a, b)    a = b
  2492. # define equalSHORTCARD(a, b)   a = b
  2493. # define equalLONGCARD(a, b)    a = b
  2494. # define equalREAL(a, b)        a = b
  2495. # define equalLONGREAL(a, b)    a = b
  2496. # define equalBOOLEAN(a, b)     a = b
  2497. # define equalCHAR(a, b)        a = b
  2498. # define equalBITSET(a, b)      a = b
  2499. # define equalBYTE(a, b)        a = b
  2500. # define equalWORD(a, b)        a = b
  2501. # define equalADDRESS(a, b)     a = b
  2502. # define equaltString(a, b)     Strings.IsEqual (a, b)
  2503. # define equaltStringRef(a, b)  a = b
  2504. # define equaltIdent(a, b)      a = b
  2505. # define equaltText(a, b)       FALSE
  2506. # define equaltSet(a, b)        Sets.IsEqual (a, b)
  2507. # define equaltRelation(a, b)   Relations.IsEqual (a, b)
  2508. # define equaltPosition(a, b)   Positions.Compare (a, b) = 0
  2509.  
  2510. References
  2511.  
  2512. [Gro90]
  2513.      J. Grosch, Specification of a Minilax  Interpreter,  Compiler  Generation
  2514.      Report  No.  22,  GMD Forschungsstelle an der Universitat Karlsruhe, Mar.
  2515.      1990.
  2516.  
  2517. [Gro91]
  2518.      J. Grosch,  Ast  -  A  Generator  for  Abstract  Syntax  Trees,  Compiler
  2519.      Generation  Report  No.  15,  GMD  Forschungsstelle  an  der  Universitat
  2520.      Karlsruhe, Sep. 1991.
  2521.  
  2522.  
  2523.  
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.                                      Puma                                    1
  2532.  
  2533.  
  2534. Contents
  2535.  
  2536. 1.      Introduction ....................................................    1
  2537. 2.      Overview ........................................................    2
  2538. 3.      Input Language ..................................................    2
  2539. 3.1.    Notation ........................................................    2
  2540. 3.2.    Lexical Conventions .............................................    3
  2541. 3.3.    Structure .......................................................    4
  2542. 3.4.    Target Code .....................................................    5
  2543. 3.5.    Subroutines .....................................................    6
  2544. 3.6.    Types ...........................................................    7
  2545. 3.7.    Rules ...........................................................    7
  2546. 3.8.    Patterns ........................................................    9
  2547. 3.9.    Expressions .....................................................   10
  2548. 3.10.   Statements ......................................................   12
  2549. 3.11.   Equality Operations .............................................   15
  2550. 3.12.   Begin Operations ................................................   16
  2551. 3.13.   Output Statements ...............................................   16
  2552. 4.      Scopes ..........................................................   17
  2553. 5.      Output ..........................................................   17
  2554. 6.      Usage ...........................................................   18
  2555.         Appendix 1: Syntax Summary ......................................   21
  2556.         Appendix 2: Examples from MiniLAX ...............................   27
  2557.         Appendix 2.1: Abstract Syntax ...................................   27
  2558.         Appendix 2.2: Generation of Intermediate Code ...................   30
  2559.         Appendix 2.3: Procedures for Type Handling ......................   33
  2560.         Appendix 3: Equality Operations .................................   37
  2561.         Appendix 3.1: C .................................................   37
  2562.         Appendix 3.2: Modula-2 ..........................................   37
  2563.         References ......................................................   37
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.